#include<iostream>
using namespace std;

/**
 * 多维数组：
 *  拆开看多维数组，每个维度就是一个一维数组，他的元素类型就是低维度数组，一直到元素类型等于数组基本元素类型的最低维度数组
 * */

/**
 * 用户信息定义结构体
 * 观察数组大小用，这里引出了结构体大小的规则问题，
 * 
 * sizeof(tagUserInfo) = 48；为什么不是32+4+8=44，而是48呢？
 * 课后作业：
 *  查阅资料看下结构体计算大小的内存对其和填充机制！
 *  下面的结构体调整下字段的顺序，结构体大小会变化吗？测试下！！！
 * */
struct tagUserInfo {
    char    userName[32];   //32byte
    int         age;        //4byte,但会填充到8个byte
    double      money;      //8byte

    /* c++结构体允许写构造函数，进行一些初始化工作
    tagUserInfo(){
        memset(userName, 0x00, 32);
        age = 0;
        money = 0;

        //这里加入设置了值，可以去掉后面结构体声明后的初始化，观察字段的值
        memcpy(userName, "changjr", 7);
    }
    */
};

int main() {
    cout << "观察多维度数组各维度之间的关系==================" << endl;
    int arr[2][3] = {
        {11,12,13}, //第一行
        {21,22,23}  //第二行
    };

    //多维度数组变量名持有的就是第一个最高维度数组的第一个元素的地址    
    //他俩输出是一样的    
    cout << arr << endl;
    cout << &arr[0][0] << endl;
    /*
    $ ./test
        0x28cd10
        0x28cd10
        11
    */
    //下标方式访问
    cout << arr[0][0] << endl;

    //看下高纬度数组的元素大小
    cout << sizeof(arr[0]) << endl;
    //12
    //数组的元素类型int占4个字节sizeof(int) ， sizeof(arr[0]) = sizeof(int) * 元素个数3 = 12

    cout << "观察多维度数组基本类型为结构体时候的情况==================" << endl;
    //这里顺道观察下结构体声明后的初始化

    //先声明，再通过memset方式设置这块内存的值都为0x00;
    tagUserInfo userList[2][5];
    memset(userList, 0x00, sizeof(userList));   //这样也可以
    
    //好像这样也可以
    //tagUserInfo userList[2][5] = {0};

    cout << "结构体tagUserInfo的大小=" << sizeof(tagUserInfo) << endl; //48
    cout << "userList的大小=" << sizeof(userList) << endl;
    cout << "第一维度元素的大小=" << sizeof(userList[0]) << endl; //240 = 48 * 5;

    cout << userList << endl;

    for(int i=0; i<2; i++){
        for(int m=0; m<5; m++){
            cout << "第" << i << "行,第" << m << "列用户的名字=" << userList[i][m].userName<< endl;
        }
    }
    cout << userList[0][0].userName << endl;
    
    int arr2[2][3] = {
        {11,12,13}, //第一行
        {21,22,23}  //第二行
    };
    cout << arr2[1][1] << endl;

    return 0;
}
/**
 * $ ./test
*/
